package com.pet.common.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.experimental.UtilityClass;
import lombok.extern.log4j.Log4j2;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/** @author Centaurea */
@Log4j2
@UtilityClass
public class JacksonUtil {
  private static final ObjectMapper mapper = new ObjectMapper();

  /**
   * 获取mapper对象
   *
   * @return mapper对象
   */
  public ObjectMapper getMapper() {
    return mapper;
  }
  /**
   * 序列化对象（转json）
   *
   * @param obj 序列化的对象
   * @return java.lang.String
   */
  public static String serialize(Object obj) {
    if (obj == null) {
      return null;
    }
    if (obj.getClass() == String.class) {
      return (String) obj;
    }
    try {
      return mapper.writeValueAsString(obj);
    } catch (JsonProcessingException e) {
      log.error("json序列化出错：" + obj, e);
      return null;
    }
  }

  /**
   * 反序列化（json转为Bean）
   *
   * @param json json
   * @param tClass 对象类型
   * @return T
   */
  public static <T> T parse(String json, Class<T> tClass) {
    try {
      return mapper.readValue(json, tClass);
    } catch (IOException e) {
      log.error("json解析出错：" + json, e);
      return null;
    }
  }

  /**
   * 反序列化（json转List）
   *
   * @param json json
   * @param eClass 对象类型
   * @return java.util.List<E>
   */
  public static <E> List<E> parseList(String json, Class<E> eClass) {
    try {
      return mapper.readValue(
          json, mapper.getTypeFactory().constructCollectionType(List.class, eClass));
    } catch (IOException e) {
      log.error("json解析出错：" + json, e);
      return null;
    }
  }

  /**
   * 反序列化（json转Map）
   *
   * @param json json
   * @param kClass key类型
   * @param vClass value类型
   * @return java.util.Map<K,V>
   */
  public static <K, V> Map<K, V> parseMap(String json, Class<K> kClass, Class<V> vClass) {
    try {
      return mapper.readValue(
          json, mapper.getTypeFactory().constructMapType(Map.class, kClass, vClass));
    } catch (IOException e) {
      log.error("json解析出错：" + json, e);
      return null;
    }
  }

  /**
   * json转复杂对象
   *
   * @param json json
   * @param type 类型
   * @return T
   */
  public static <T> T nativeRead(String json, TypeReference<T> type) {
    try {
      return mapper.readValue(json, type);
    } catch (IOException e) {
      log.error("json解析出错：" + json, e);
      return null;
    }
  }
}
